/*
 *  Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.keter.dtx.controller;

import com.keter.dtx.service.tcc.TccActionOne;
import com.keter.dtx.service.tcc.TccActionTwo;
import com.keter.framework.core.exception.ValidateException;
import io.seata.spring.annotation.GlobalTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * The type Asset controller.
 */
@Controller
@RequestMapping
public class TCCController {
	private static final Logger logger = LoggerFactory.getLogger(TCCController.class);
	/**
	 * The Port.
	 */
	@Value("${server.port}")
	String port;

	@Autowired
	TccActionOne tccActionOne;
	@Autowired
	TccActionTwo tccActionTwo;

	/**
	 * 测试提交成功
	 * @param name
	 * @return
	 */
	@RequestMapping(value = "/tcc/success")
	@ResponseBody
	@GlobalTransactional
	public String success(String name) {
		//第一个TCC 事务参与者
		tccMock(name);
		return "success";
	}

	/**
	 * 测试回滚
	 * @param name
	 * @return
	 */
	@RequestMapping(value = "/tcc/rollback")
	@ResponseBody
	// @GlobalTransactional注解必须放在此处，不能放在内部方法上。
	// 否则会导致BusinessActionContext为空
	@GlobalTransactional
	public String rollback(String name) {
		tccErrorMock(name);
		return "rollback mock!";
	}

	private void tccMock(String name) {
		// 第一个TCC 事务参与者
		boolean result = tccActionOne.prepare(null, 1, name);
		if (!result) {
			throw new RuntimeException("TccAction1 failed.");
		}
		result = tccActionTwo.prepare(null, name);
		if (!result) {
			throw new RuntimeException("TccAction2 failed.");
		}
	}

	private void tccErrorMock(String name) {
		tccMock(name);
		// 截止到@GlobalTransactional方法结束时，不出现任何异常才会执行COMMIT操作，否则直接回滚！
		throw new ValidateException("事务回滚异常模拟!");
	}
}
